#include "global.h"
#include "battle_anim.h"
#include "legend_battle.h"
#include "random.h"
#include "event_data.h"
#include "item.h"
#include "string_util.h"
#include "constants/legend_battle.h"
#include "constants/moves.h"

u8 GetRealmAnimId(u8 type)
{
    static const u8 gLegendaryAnim[] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   B_ANIM_GROUDON_REALM,
        [LEGENDARY_MON_KYOGRE - 1] =    B_ANIM_RAIN_CONTINUES,
        [LEGENDARY_MON_RAYQUAZA - 1] =  B_ANIM_ELI_REINF,
    };

    if (type <= ARRAY_COUNT(gLegendaryAnim))
        return gLegendaryAnim[type - 1];
    else
        return 0;
}

u8 const *GetLegendaryPrefix(u8 type)
{
    static const u8 sText_LegendaryPkmnPrefix[] = _("神兽");

    static const u8 gLegendaryPrefix[][15] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   _("炎陆之王"),
        [LEGENDARY_MON_KYOGRE - 1] =    _("深渊之主"),
        [LEGENDARY_MON_RAYQUAZA - 1] =  _("苍穹之龙"),
    };

    if (type > 0 && type <= ARRAY_COUNT(gLegendaryPrefix))
        return gLegendaryPrefix[type - 1];
    else
        return sText_LegendaryPkmnPrefix;
}

u8 const *GetLegendaryRealm(u8 type)
{
    static const u8 sText_UnknownRealm[] = _("???");

    static const u8 gLegendaryRealm[][11] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   _("炽热地心"),
        [LEGENDARY_MON_KYOGRE - 1] =    _("深渊寂海"),
        [LEGENDARY_MON_RAYQUAZA - 1] =  _("平流空层"),
    };

    if (type > 0 && type <= ARRAY_COUNT(gLegendaryRealm))
        return gLegendaryRealm[type - 1];
    else
        return sText_UnknownRealm;
}

u8 const *GetLegendaryRealmIntro(u8 type)
{
    static const u8 RealmText_Unknown[]     = _("还没有制作{B_OPPONENT_MON1_NAME}的\n领域效果!");
    static const u8 RealmText_Groudon[]     = _("{B_OPPONENT_MON1_NAME}将免疫地面系及火系技能，\n并永久向场地施加重力效果！\p同时，我方宝可梦将在每回合末由于\n高温损失1/8的生命值！\p此外，{B_OPPONENT_MON1_NAME}灼热的身躯将会引燃\n对其使用接触招式的宝可梦！");
    static const u8 RealmText_Kyogre[]      = _("{B_OPPONENT_MON1_NAME}将免疫电系及水系技能，\p同时，在每回合末，\n{B_OPPONENT_MON1_NAME}都会召唤深渊淹没我方宝可梦，\p其效果相当于60威力的水系特攻招式！");
    static const u8 RealmText_Rayquaza[]    = _("{B_OPPONENT_MON1_NAME}将免疫接触攻击，\n并对地上的宝可梦造成1.5倍伤害！\p同时，{B_OPPONENT_MON1_NAME}的招式将拥有\n额外的先制度。\p此外，由于乱流的影响，我方宝可梦\n将会在回合末下降一级的双攻与命中！\p且这一过程不会受到特性的影响！");

    static const u8 *const gLegendaryRealmIntro[] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   RealmText_Groudon,
        [LEGENDARY_MON_KYOGRE - 1] =    RealmText_Kyogre,
        [LEGENDARY_MON_RAYQUAZA - 1] =  RealmText_Rayquaza,
    };

    if (type > 0 && type <= ARRAY_COUNT(gLegendaryRealmIntro))
        return gLegendaryRealmIntro[type - 1];
    else
        return RealmText_Unknown;
}

u8 const *GetLegendaryRealmSpeech(u8 type)
{
    static const u8 RealmText_Unknown[]     = _("……");
    static const u8 RealmText_Groudon[]     = _("让……大地……\n更为之震颤吧……");
    static const u8 RealmText_Kyogre[]      = _("光层无法通过，\n深渊也无法通过。");
    static const u8 RealmText_rayquaza[]    = _("无需过多的紧张，\n坚信你正确的路线即可。");

    static const u8 *const gLegendaryRealmSpeech[] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   RealmText_Groudon,
        [LEGENDARY_MON_KYOGRE - 1] =    RealmText_Kyogre,
        [LEGENDARY_MON_RAYQUAZA - 1] =  RealmText_rayquaza,
    };

    if (type > 0 && type <= ARRAY_COUNT(gLegendaryRealmSpeech))
        return gLegendaryRealmSpeech[type - 1];
    else
        return RealmText_Unknown;
}

u8 const *GetWonLegendarySpeech(u8 type)
{
    static const u8 WonText_Unknown[]     = _("……");
    static const u8 WonText_Groudon[]     = _("原来如此……\p那份比岩浆还要滚烫的……\n炽热的心脏……\p我已经感受到了……");
    static const u8 WonText_Kyogre[]      = _("原来如此。\p那份比礁石还要稳定的……\n冷静的大脑……\p我已经感受到了。");
    static const u8 WonText_rayquaza[]    = _("……不出意料\p这份即使浮动的理想，\n也永远不会改变啊。");

    static const u8 *const gWonLegendarySpeech[] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   WonText_Groudon,
        [LEGENDARY_MON_KYOGRE - 1] =    WonText_Kyogre,
        [LEGENDARY_MON_RAYQUAZA - 1] =  WonText_rayquaza,
    };

    if (type > 0 && type <= ARRAY_COUNT(gWonLegendarySpeech))
        return gWonLegendarySpeech[type - 1];
    else
        return WonText_Unknown;
}

u8 const *GetLostLegendarySpeech(u8 type)
{
    static const u8 LostText_Unknown[]     = _("……");
    static const u8 LostText_Groudon[]     = _("这样是无法满足我的……\n也丝毫无法让大地出现裂纹……");
    static const u8 LostText_Kyogre[]      = _("这样，远远不够。\n也丝毫无法让海面出现波纹。");
    static const u8 LostText_rayquaza[]    = _("天空未能划破，\n你的选择也可重来数次");

    static const u8 *const gLostLegendarySpeech[] =
    {
        [LEGENDARY_MON_GROUDON - 1] =   LostText_Groudon,
        [LEGENDARY_MON_KYOGRE - 1] =    LostText_Kyogre,
        [LEGENDARY_MON_RAYQUAZA - 1] =  LostText_rayquaza,
    };

    if (type > 0 && type <= ARRAY_COUNT(gLostLegendarySpeech))
        return gLostLegendarySpeech[type - 1];
    else
        return LostText_Unknown;
}

u32 GetLegendaryPID(u8 type)
{
    static const u8 LegendaryNatures[] = {
        [LEGENDARY_MON_GROUDON - 1] =   NATURE_ADAMANT,
        [LEGENDARY_MON_KYOGRE - 1] =    NATURE_MODEST,
        [LEGENDARY_MON_RAYQUAZA - 1] =  NATURE_JOLLY,
    };

    if (type > 0 && type <= ARRAY_COUNT(LegendaryNatures))
    {
        u32 PID;

        do
            PID = Random32();
        while (LegendaryNatures[type - 1] != GetNatureFromPersonality(PID));

        return PID;
    }
    else
        return Random32();
}

void SetLegendaryMoves(u8 type)
{
    static const u16 LegendaryMoves[][MAX_MON_MOVES] = {
        [LEGENDARY_MON_GROUDON - 1] =   {MOVE_PRECIPICE_BLADES, MOVE_HEAT_CRASH, MOVE_STONE_EDGE, MOVE_SWORDS_DANCE},
        [LEGENDARY_MON_KYOGRE - 1] =    {MOVE_ORIGIN_PULSE, MOVE_ICE_BEAM, MOVE_THUNDER, MOVE_CALM_MIND},
        [LEGENDARY_MON_RAYQUAZA - 1] =  {MOVE_DRAGON_ASCENT, MOVE_V_CREATE, MOVE_EARTHQUAKE, MOVE_DRAGON_DANCE},
    };

    u8 i;

    if (type > 0 && type <= ARRAY_COUNT(LegendaryMoves))
    {
        for (i = 0; i < MAX_MON_MOVES; i++)
            SetMonData(&gEnemyParty[0], MON_DATA_MOVE1 + i, &LegendaryMoves[type - 1][i]);
    }

    for (i = 0; i < 4; i++)
        SetMonData2(&gEnemyParty[0], MON_DATA_PP1 + i,
                    CalculatePPWithBonus(GetMonData(&gEnemyParty[0],
                                                    MON_DATA_MOVE1 + i, NULL), 255, i)); //pp加成一定255
}

void SetLegendaryAbilityNum(u8 type)
{
    static const u8 abilityNums[] = {
        [LEGENDARY_MON_GROUDON - 1]  = 0,
        [LEGENDARY_MON_KYOGRE - 1]   = 0,
        [LEGENDARY_MON_RAYQUAZA - 1] = 0,
    };

    if (type > 0 && type <= ARRAY_COUNT(abilityNums))
        SetMonData(&gEnemyParty[0], MON_DATA_ABILITY_NUM, &abilityNums[type - 1]);
}

void SetRemembranceTower(void)
{
    u8 slot = (gLegendaryMon - 1) / 4;
    u8 mod  = (gLegendaryMon - 1) % 4;

    gSaveBlock1Ptr->remembranceTower[slot] &= ~(3 << (mod * 2)); // 00 01 10 11 3->11b
    gSaveBlock1Ptr->remembranceTower[slot] |= (gSpecialVar_0x8003 << (mod * 2));
}

u8 GetRemembranceTower(u8 legendaryId)
{
    u8 slot = (legendaryId - 1) / 4;
    u8 mod  = (legendaryId - 1) % 4;

    return 3 & (gSaveBlock1Ptr->remembranceTower[slot] >> (mod * 2));
}

void CopyVoucherName(u16 itemId, u8 *dst)
{
    static const u8 LegendarySuffix[][4] = {
        _("-铁"),
        _("-铜"),
        _("-银"),
        _("-金"),
    };

    CopyItemName(itemId, dst);
    StringAppend(dst, LegendarySuffix[GetRemembranceTower(ItemId_GetSecondaryId(itemId))]);
}

void CopyVoucherDescription(u16 itemId, u8 *dst)
{
    static const u8 DescriptionSuffix[][10] = {
        _("黑铁凭证。"),
        _("青铜凭证。"),
        _("白银凭证。"),
        _("黄金凭证。"),
    };

    StringCopy(dst, ItemId_GetDescription(itemId));
    StringAppend(dst, DescriptionSuffix[GetRemembranceTower(ItemId_GetSecondaryId(itemId))]);
}
